package com.hepinghospital.user.ui.activity.nursing;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatAutoCompleteTextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.CoordinateConverter;
import com.amap.api.location.DPoint;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.MapsInitializer;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.core.ServiceSettings;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.hepinghospital.user.R;
import com.hepinghospital.user.adapter.PoiSearchResultAdapter;
import com.hepinghospital.user.ui.widget.PoiOverlay;
import com.hepinghospital.user.util.ToastUtil;
import com.hepinghospital.user.util.UtilString;
import com.rest.response.NursingProjectResponse;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import jz.joyoung.robot.util.LogUtil;
import jz.joyoung.robot.util.SoftKeyboardUtil;

/**
 * @Description: 预约护理 选择地址
 * @Author: lzp
 * @CreateDate: 2022/3/7 9:23
 * @UpdateRemark: 更新说明
 */
public class AppointStep2Activity extends CheckPermissionsActivity implements PoiSearch.OnPoiSearchListener {
    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.mMapView)
    MapView mMapView;
    @BindView(R.id.edt_search)
    AppCompatAutoCompleteTextView edtSearch;
    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    @BindView(R.id.tv_next)
    TextView tvNext;

    AMap aMap = null;
    private String keyWord = "";// 要输入的poi搜索关键字
    private PoiResult poiResult; // poi返回的结果
    private PoiSearch.Query query;// Poi查询条件类
    private PoiSearch poiSearch;// POI搜索


    ArrayList<PoiItem> data = new ArrayList<>();
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;

    private AMapLocationClientOption locationOption = null;

    PoiSearchResultAdapter adapter;
    private String cityCode = "0577";//温州

    DPoint centerPoint;//温州眼视光医院位置
    DPoint dPoint;
    NursingProjectResponse.ChargeItemsBean chargeItemsBean;
    static WeakReference<Activity> mActivity = null;
    List<String> listString = new ArrayList<>();

    //声明定位回调监听器
    public AMapLocationListener mLocationListener = aMapLocation -> {
        if (aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                aMapLocation.getLocationType();//获取当前定位结果来源，如网络定位结果，详见定位类型表
                aMapLocation.getLatitude();//获取纬度
                aMapLocation.getLongitude();//获取经度
                aMapLocation.getAddress();//地址，如果option中设置isNeedAddress为false，则没有此结果，网络定位结果中会有地址信息，GPS定位不返回地址信息。
                //创建定位点坐标
                dPoint = new DPoint();
                //设置定位点纬度
                dPoint.setLatitude( aMapLocation.getLatitude() );
                //设置定位点经度
                dPoint.setLongitude( aMapLocation.getLongitude() );
                LogUtil.e( aMapLocation.toStr() );
                keyWord = aMapLocation.getPoiName();
                if (!TextUtils.isEmpty( keyWord )) {
                    stopLocation();
                }
                doSearchQuery();
            } else {
                //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                LogUtil.e( "location Error, ErrCode:"
                        + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo() );
            }
        }
    };

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        mActivity = new WeakReference<>( this );
//        privacyCompliance();
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mMapView.onCreate( savedInstanceState );
        //在构造MapView之前必须进行合规检查,设置接口之前保证隐私政策合规
        MapsInitializer.updatePrivacyShow( this, true, true );
        MapsInitializer.updatePrivacyAgree( this, true );
        //在构造PoiSearch之前必须进行合规检查（RouteSearch，WeatherSearch等也是一样的操作），设置接口之前保证隐私政策合规，检查接口如下：
        ServiceSettings.updatePrivacyShow( this, true, true );
        ServiceSettings.updatePrivacyAgree( this, true );
        initLocation();
        initMap();
    }

    private void initMap() {
        //初始化地图控制器对象
        if (aMap == null) {
            aMap = mMapView.getMap();
            setUpMap();
        }
        chargeItemsBean = (NursingProjectResponse.ChargeItemsBean) getIntent().getSerializableExtra( "item" );
    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.getUiSettings().setMyLocationButtonEnabled( true );// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled( true );// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        setupLocationStyle();
//        aMap.addOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
//            @Override
//            public void onMyLocationChange(Location location) {
//                location.getLatitude();
//                location.getLongitude();
//            }
//        });
    }

    /**
     * 设置自定义定位蓝点
     */
    private void setupLocationStyle() {
        // 自定义系统定位蓝点
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationType( MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER );
        myLocationStyle.interval( 2000 ); //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
//        // 自定义定位蓝点图标
//        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
//                fromResource(R.drawable.gps_point));
//        // 自定义精度范围的圆形边框颜色
//        myLocationStyle.strokeColor(STROKE_COLOR);
//        //自定义精度范围的圆形边框宽度
//        myLocationStyle.strokeWidth(5);
//        // 设置圆形的填充颜色
//        myLocationStyle.radiusFillColor(FILL_COLOR);
        // 将自定义的 myLocationStyle 对象添加到地图上
        aMap.setMyLocationStyle( myLocationStyle );
//        aMap.setLocationSource(this);
    }


    @Override
    protected void initViews() {
        tvTitle.setText( "选择地址" );
//        edtSearch.setOnEditorActionListener((v, actionId, event) -> {
//            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//                if (TextUtils.isEmpty(edtSearch.getText().toString())) {
//                    ToastUtil.showToast(mContext, "请输入搜索地址");
//                    return true;//保留键盘
//                }
//                keyWord = edtSearch.getText().toString();
//                doSearchQuery();
//                SoftKeyboardUtil.hideSoftKeyboard(mContext);
//            }
//            return false;//隐藏键盘
//        });
        tvNext.setOnClickListener( v -> startActivity( new Intent( AppointStep2Activity.this, AppointStep3Activity.class ) ) );
        edtSearch.addTextChangedListener( new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String newText = s.toString().trim();
                if (!UtilString.isEmpty( newText )) {
                    InputtipsQuery inputquery = new InputtipsQuery( newText, "温州" );
                    inputquery.setCityLimit( true );//限制在当前城市
                    Inputtips inputTips = new Inputtips( AppointStep2Activity.this, inputquery );
                    inputTips.setInputtipsListener( (tipList, rCode) -> {
                        if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回
                            listString.clear();
                            for (int i = 0; i < tipList.size(); i++) {
                                listString.add( tipList.get( i ).getName() );
                            }
                            ArrayAdapter<String> aAdapter = new ArrayAdapter<>(
                                    getApplicationContext(),
                                    R.layout.item_search_poi, listString );
                            edtSearch.setAdapter( aAdapter );
                            aAdapter.notifyDataSetChanged();
                        } else {
                            ToastUtil.showToast( mContext, rCode + "" );
                        }
                    } );
                    inputTips.requestInputtipsAsyn();
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        } );
        edtSearch.setOnItemClickListener( (parent, view, position, id) -> {
            keyWord = listString.get( position );
            doSearchQuery();
            SoftKeyboardUtil.hideSoftKeyboard( mContext );
        } );
        LinearLayoutManager manager = new LinearLayoutManager( this );
        manager.setOrientation( LinearLayoutManager.VERTICAL );
        recyclerView.setLayoutManager( manager );

        adapter = new PoiSearchResultAdapter( data );
        recyclerView.setAdapter( adapter );
        adapter.setOnItemClickListener( (adapter1, view, position) -> {
            try {
                if (dPoint == null) {
                    dPoint = new DPoint();
                }
                dPoint.setLatitude( data.get( position ).getLatLonPoint().getLatitude() );
                dPoint.setLongitude( data.get( position ).getLatLonPoint().getLongitude() );
                float distance = CoordinateConverter.calculateLineDistance( centerPoint, dPoint );
//                ToastUtil.showToast(mContext, distance / 1000 + "公里");
                if (distance > 15000) {
                    ToastUtil.showToast( mContext, "该地址超出服务范围" );
                    return;
                }
                Bundle bundle = new Bundle();
                bundle.putSerializable( "item", chargeItemsBean );
                bundle.putString( "address", data.get( position ).getTitle() );
                bundle.putString( "distance", distance + "" );
                bundle.putString( "longitude", data.get( position ).getLatLonPoint().getLongitude() + "" );
                bundle.putString( "latitude", data.get( position ).getLatLonPoint().getLatitude() + "" );
                startActivity( AppointStep3Activity.class, bundle );
            } catch (Exception e) {
                e.printStackTrace();
            }
        } );
        showLoadingDialog( this );
    }

    @Override
    protected void initData() {
        centerPoint = new DPoint( 28.007848, 120.672057 );
    }

    @Override
    protected int getLayoutResource() {
        return R.layout.activity_nursing_appoint_step2;
    }

    /**
     * 开始进行poi搜索
     */
    protected void doSearchQuery() {
        query = new PoiSearch.Query( keyWord, "", cityCode );// 第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        query.setPageSize( 10 );// 设置每页最多返回多少条poiitem
        // 当前页面，从0开始计数
        int currentPage = 0;
        query.setPageNum( currentPage );// 设置查第一页
        try {
            poiSearch = new PoiSearch( this, query );
            poiSearch.setOnPoiSearchListener( this );
            if (poiSearch != null) {
                poiSearch.searchPOIAsyn();
            }
        } catch (AMapException e) {
            LogUtil.e( e.getErrorMessage() );
            dismissLoadingDialog();
        }
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        //初始化client
        try {
            mLocationClient = new AMapLocationClient( this.getApplicationContext() );
            locationOption = getDefaultOption();
            //设置定位参数
            mLocationClient.setLocationOption( locationOption );
            // 设置定位监听
            mLocationClient.setLocationListener( mLocationListener );
            startLocation();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 默认的定位参数
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy );//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst( true );//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut( 30000 );//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval( 5 );//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress( true );//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation( false );//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest( false );//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol( AMapLocationClientOption.AMapLocationProtocol.HTTP );//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable( false );//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan( true ); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable( true ); //可选，设置是否使用缓存定位，默认为true
        mOption.setGeoLanguage( AMapLocationClientOption.GeoLanguage.DEFAULT );//可选，设置逆地理信息的语言，默认值为默认语言（根据所在地区选择语言）
        return mOption;
    }


    private void privacyCompliance() {
        MapsInitializer.updatePrivacyShow( this, true, true );
        SpannableStringBuilder spannable = new SpannableStringBuilder( "\"亲，感谢您对XXX一直以来的信任！我们依据最新的监管要求更新了XXX《隐私权政策》，特向您说明如下\n1.为向您提供交易相关基本功能，我们会收集、使用必要的信息；\n2.基于您的明示授权，我们可能会获取您的位置（为您提供附近的商品、店铺及优惠资讯等）等信息，您有权拒绝或取消授权；\n3.我们会采取业界先进的安全措施保护您的信息安全；\n4.未经您同意，我们不会从第三方处获取、共享或向提供您的信息；\n" );
        spannable.setSpan( new ForegroundColorSpan( Color.BLUE ), 35, 42, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
        new AlertDialog.Builder( this )
                .setTitle( "温馨提示(隐私合规示例)" )
                .setMessage( spannable )
                .setPositiveButton( "同意", (dialogInterface, i) -> {
                    MapsInitializer.updatePrivacyAgree( AppointStep2Activity.this, true );
                    initLocation();
                    initMap();
                } )
                .setNegativeButton( "不同意", (dialogInterface, i) -> MapsInitializer.updatePrivacyAgree( AppointStep2Activity.this, false ) )
                .show();
    }


    /**
     * 开始定位
     */
    private void startLocation() {
        try {
            // 启动定位
            if (mLocationClient != null) {
                mLocationClient.startLocation();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 停止定位
     */
    private void stopLocation() {
        try {
            // 停止定位
            if (mLocationClient != null) {
                mLocationClient.stopLocation();//停止定位后，本地定位服务并不会被销毁
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 销毁定位
     */
    private void destroyLocation() {
        if (null != mLocationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            mLocationClient.onDestroy();
            mLocationClient = null;
            locationOption = null;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState( outState );
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mMapView.onSaveInstanceState( outState );
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume ()，重新绘制加载地图
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause ()，暂停地图的绘制
        mMapView.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopLocation();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy()，销毁地图
        mMapView.onDestroy();
        destroyLocation();
        if (mActivity != null) {
            mActivity.clear();
            mActivity = null;
        }
    }

    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                if (result.getQuery().equals( query )) {// 是否是同一条
                    poiResult = result;
                    // 取得搜索到的poiitems有多少页
                    List<PoiItem> poiItems = poiResult.getPois();// 取得第一页的poiitem数据，页数从数字0开始
                    data.clear();
                    data.addAll( poiItems );
                    adapter.notifyDataSetChanged();
                    if (poiItems.size() > 0) {
                        aMap.clear();// 清理之前的图标
                        PoiOverlay poiOverlay = new PoiOverlay( aMap, poiItems );
                        poiOverlay.removeFromMap();
                        poiOverlay.addToMap();
                        poiOverlay.zoomToSpan();
                    }
                }
            } else {
                ToastUtil.showToast( mContext, "没有结果" );
            }
            LogUtil.e( "onPoiSearched搜索成功" );
        } else {
            LogUtil.e( "搜索poi错误：" + rCode );
        }
        dismissLoadingDialog();
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int rCode) {
        LogUtil.e( "onPoiItemSearched" );
    }

    public static void clsoeSelf() {
        if (mActivity != null && mActivity.get() != null) {
            Activity context = mActivity.get();
            context.finish();
        }
    }
}
